package com.ethjava.usdx;


import com.ethjava.utils.Environment;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.ChainId;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * 发起交易
 */
public class Transaction {

    private static Web3j web3j;
    private static String fromAddress = "0x024c3adeD3ACAD90687a8eD1B1460Ad8DE871534";
    private static String toAddress = "0x392d6168d79d81F9Ce1764f8AA1ff6537f4B1773";
    private static String privateKey = "80e2c548d0efa1aa3d8e0de168f43b8691275e67beb37aa5115f6baeaf67f20d";
    private static String data = "";
    private static BigInteger gasPrice = Convert.toWei(BigDecimal.valueOf(10), Convert.Unit.GWEI).toBigInteger();
    private static BigInteger gasLimit = BigInteger.valueOf(30000);
    private static BigInteger amount = Convert.toWei(BigDecimal.valueOf(0.2), Convert.Unit.ETHER).toBigInteger();

    public static void main(String[] args) {

        web3j = Web3j.build(new HttpService(Environment.RPC_URL));

        testTransaction();
    }

    private static void testTransaction() {
        EthGetTransactionCount ethGetTransactionCount = null;
        try {
            ethGetTransactionCount = web3j.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.PENDING).send();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (ethGetTransactionCount == null) {
            return;
        }
        BigInteger nonce = ethGetTransactionCount.getTransactionCount();

        String signedData;
        try {
            signedData = signTransaction(nonce, gasPrice, gasLimit, toAddress, amount, data, ChainId.NONE, privateKey);
            if (signedData != null) {
                EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(signedData).send();
                System.out.println(ethSendTransaction.getTransactionHash());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String signTransaction(BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to,
                                         BigInteger value, String data, byte chainId, String privateKey) throws IOException {
        byte[] signedMessage;
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, value, data);
        if (privateKey.startsWith("0x")) {
            privateKey = privateKey.substring(2);
        }
        ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
        Credentials credentials = Credentials.create(ecKeyPair);
        if (chainId > ChainId.NONE) {
            signedMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials);
        } else {
            signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        }
        String hexValue = Numeric.toHexString(signedMessage);
        return hexValue;
    }
}
